Global state

In RL, there is no global state. All of a module's global state has to be passed to its functions. However, instead of bleeding the dependency on global state through the whole codebase, RL allows injecting context:

CONTEXT counter: UM;

track() UM := counter += 1;
tracked_action() VOID
{
    IF(track() & 1)
        ...;
    ELSE
        ...;
}

main() INT
{
    []{counter: 0} tracked_action();
    []{counter: 0} tracked_action();
    int counter2 := 0;
    []{counter: counter2} tracked_action();
    ASSERT(counter2 == 1);
    []{counter: counter2} tracked_action();
    ASSERT(counter2 == 2)
    = 0;
}

CONTEXT variables are references that are bound at runtime. This means that variables passed as a context argument are passed by reference and can be modified by the called function. When passing a temporary, immediate or constant value as a context argument to a mutable context variable, a hidden local variable is created and passed instead.

Lifetime

A context variable's lifetime is considered to only last as long as the current function executes. Only immutable context variables can be passed to coroutines and other threads.